//
//  FlickrSearcher.m
//  FlickrSearch-UICollectionView
//
//  Created by cygarm on 15/10/4.
//  Copyright © 2015年 cygarm. All rights reserved.
//
#import "FlickrSearcher.h"

static NSString * const kAPIKey = @"d1c5b3605ca0692cb722e227012a6274";


@implementation FlickrSearchResults

- (instancetype)init
{
	if (self = [super init]) {
		self.searchTerm = @"";
		self.searchResults = [NSMutableArray array];
	}
	return self;
}

- (instancetype)initWithSearchTerm:(NSString *)searchTerm 
										 searchResults:(NSMutableArray *)searchResults
{
	if (self = [super init]) {
		self.searchTerm = searchTerm;
		self.searchResults = searchResults;
	}
	return self;
}

@end

@implementation FlickrPhoto

- (instancetype)initWithPhotoID:(NSString *)photoID 
													 farm:(NSInteger)farm 
												 server:(NSString *)server 
												 secret:(NSString *)secret
{
	if (self = [super init]) {
		self.photoID = photoID;
		self.farm = farm;
		self.server = server;
		self.secret = secret;
	}
	return self;
}

- (NSURL *)flickrImageURLOfSize:(NSString *)size
{
	if (!size) {
		size = @"m";
	}
	return [NSURL URLWithString:[NSString stringWithFormat:@"https://farm%ld.staticflickr.com/%@/%@_%@_%@.jpg", 
															 (long)self.farm,
															 self.server,
															 self.photoID,
															 self.secret,
															 size]];
}

- (void)loadLargeImageWithCompletion:(void(^)(FlickrPhoto *flickrPhoto, NSError *error))completion
{
	NSURL *loadURL = [self flickrImageURLOfSize:@"b"];
	NSURLRequest *loadRequest = [NSURLRequest requestWithURL:loadURL];
	NSLog(@"loadRequest:%@", loadRequest);
#if 0
	NSURLSession *session = [NSURLSession sharedSession];
	NSURLSessionDataTask *task = [session dataTaskWithRequest:loadRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
		
		NSLog(@"loadRequest session end");

		if (error != nil) {
			completion(self, nil);
		}
		
		if (data != nil) {
			UIImage *returnedImage = [UIImage imageWithData:data];
			self.largeImage = returnedImage;
			completion(self, nil);
			return;
		}
		
		completion(self, nil);
		
	}];
#else
	AFURLSessionManager *manager = [[AFURLSessionManager alloc] init];
	manager.responseSerializer = [AFImageResponseSerializer serializer];
	NSURLSessionDataTask *task = [manager dataTaskWithRequest:loadRequest completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
		NSLog(@"loadRequest session end");
		if (error != nil) {
			completion(self, nil);
		}
		if (responseObject != nil) {
			self.largeImage = responseObject;
			completion(self, nil);
			return;
		}
		completion(self, nil);
	}];
#endif
	
	[task resume];
}

- (CGSize) sizeToFillWidthOfSize:(CGSize)size
{
	if (self.thumbnail == nil) {
		return size;
	}
	
	CGSize imageSize = self.thumbnail.size;
	CGSize returnSize = size;
	double aspectRatio = imageSize.width / imageSize.height;
	returnSize.height = returnSize.width / aspectRatio;
	
	if (returnSize.height > size.height) {
		returnSize.height = size.height;
		returnSize.width = size.width * aspectRatio;
	}
	
	return returnSize;
}

- (BOOL)isEqual:(id)object
{
	return self.photoID == ((FlickrPhoto *)object).photoID;
}

@end

@implementation Flickr

- (NSURL *)flickrSearchURLForSearchTerm:(NSString *)searchTerm
{
	searchTerm = [searchTerm stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]];
	
	NSString *URLString = [NSString stringWithFormat:@"https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=%@&text=%@&per_page=5&format=json&nojsoncallback=1", kAPIKey, searchTerm];
	
	return [NSURL URLWithString:URLString];
}

- (void)searchFlickrForTerm:(NSString *)searchTerm 
								 JSONResult:(NSDictionary *)resultDictionary 
								 completion:(void(^)(FlickrSearchResults *results, NSError *error))completion
{
	NSString *status = resultDictionary[@"stat"];
	if ([status isEqualToString:@"ok"]) {
		NSLog(@"Results processed OK");
	} else if ([status isEqualToString:@"fail"]) {
		NSError *APIError = [[NSError alloc] initWithDomain:@"FlickrSearch" 
																									 code:0 
																							 userInfo:@{NSLocalizedFailureReasonErrorKey: resultDictionary[@"message"]}];
		completion(nil, APIError);
		return;
	}	else {
		NSError *APIError = [[NSError alloc] initWithDomain:@"FlickrSearch" 
																									 code:0 
																							 userInfo:@{NSLocalizedFailureReasonErrorKey: @"Uknown API response"}];
		completion(nil, APIError);
		return;
	}
	
	NSArray *photosReceived = resultDictionary[@"photos"][@"photo"];
	NSMutableArray *flickrPhotos = [@[] mutableCopy];
	
	for (NSMutableDictionary *photoDictionary in photosReceived) {
		NSString *photoID = photoDictionary[@"id"];
		NSInteger farm = [photoDictionary[@"farm"] integerValue];
		NSString *server = photoDictionary[@"server"];
		NSString *secret = photoDictionary[@"secret"];
		
		FlickrPhoto *flickrPhoto = [[FlickrPhoto alloc] initWithPhotoID:photoID farm:farm server:server secret:secret];
		NSData *imageData = [[NSData alloc] initWithContentsOfURL:[flickrPhoto flickrImageURLOfSize:nil]];
		flickrPhoto.thumbnail = [UIImage imageWithData:imageData];
		
		[flickrPhotos addObject:flickrPhoto];
	}
	
	dispatch_async(dispatch_get_main_queue(), ^{
		completion([[FlickrSearchResults alloc] initWithSearchTerm:searchTerm searchResults:flickrPhotos], nil);
	});
}

- (void)searchFlickrForTerm:(NSString *)searchTerm 
								 completion:(void(^)(FlickrSearchResults *results, NSError *error))completion
{	
	NSURL *searchURL = [self flickrSearchURLForSearchTerm:searchTerm];
	NSURLRequest *searchRequest = [NSURLRequest requestWithURL:searchURL];
	NSLog(@"searchRequest:%@", searchRequest);
	
	__weak Flickr *weakSelf = self;
#if 0
	NSURLSession *session = [NSURLSession sharedSession];
	NSURLSessionDataTask *task = [session dataTaskWithRequest:searchRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
		
		NSLog(@"searchRequest session end");
		
		if (error != nil) {
			completion(nil, error);
			return;
		}
		
		NSLog(@"data=%@", data);
		
		NSError *JSONError = nil;
		NSDictionary *resultDictionary = [NSJSONSerialization JSONObjectWithData:data
																																		 options:kNilOptions
																																			 error:&JSONError];
		if (JSONError != nil) {
			completion(nil, JSONError);
			return;
		}
		NSLog(@"resultDictionary=%@", resultDictionary);
		
		Flickr *innerSelf = weakSelf;
		[innerSelf searchFlickrForTerm:searchTerm JSONResult:resultDictionary completion:completion];
	}];
#else
	#if 0
		NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
		AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
		manager.responseSerializer = [AFJSONResponseSerializer serializer];
		
		NSURLSessionDataTask *task = [manager dataTaskWithRequest:searchRequest completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
			NSLog(@"JSON: %@", responseObject);
			if (error != nil) {
				completion(nil, error);
				return;
			}
			
			Flickr *innerSelf = weakSelf;
			[innerSelf searchFlickrForTerm:searchTerm JSONResult:responseObject completion:completion];
		}];
	#else
		NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
		AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithSessionConfiguration:configuration];
		manager.responseSerializer = [AFJSONResponseSerializer serializer];
		
		NSURLSessionDataTask *task = [manager GET:[searchURL relativeString] parameters:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nonnull responseObject) {
			NSLog(@"JSON: %@", responseObject);
			
			Flickr *innerSelf = weakSelf;
			[innerSelf searchFlickrForTerm:searchTerm JSONResult:responseObject completion:completion];
		} failure:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nonnull error) {
			completion(nil, error);
			return;
		}];
	#endif
#endif
	
	[task resume];
}

@end



